
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Spring事件机制 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Spring事件机制 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Spring事件机制是基于什么设计模式实现的？它的主要作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring事件机制基于发布-订阅模式实现。它的主要作用是让应用的不同部分可以相互通信而不直接依赖于彼此，从而解耦各个组件之间的关系，使得模块功能更加独立。</div>
          </div>
          <div class="card-source">来源: 1. Spring 事件机制概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">请列举并简要描述Spring事件机制中的四个核心类或接口。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. ApplicationEvent：所有事件的基类。<br>2. ApplicationListener：事件监听器接口，用于监听事件。<br>3. ApplicationEventPublisher：事件发布者接口，用于发布事件。<br>4. SimpleApplicationEventMulticaster：事件多播器，用于将事件分发给所有符合条件的监听器。</div>
          </div>
          <div class="card-source">来源: 2. Spring 事件机制的核心类</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在Spring中，事件是如何被发布的？ApplicationContext的`publishEvent()`方法内部做了什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">事件通常通过 ApplicationContext 来发布，因为它实现了 ApplicationEventPublisher 接口。`publishEvent()`方法内部会首先验证事件不为空，然后获取事件多播器（ApplicationEventMulticaster），最后调用多播器的 `multicastEvent()` 方法来分发事件。</div>
          </div>
          <div class="card-source">来源: 3. 事件发布的实现流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何实现一个Spring事件监听器来处理自定义事件？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过创建一个类并实现 `ApplicationListener<E extends ApplicationEvent>` 接口，其中E是具体的事件类型。然后，在该类中重写 `onApplicationEvent(E event)` 方法，当特定类型的事件被发布时，这个方法就会被调用来执行处理逻辑。</div>
          </div>
          <div class="card-source">来源: 4. 事件监听器的实现流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Spring中的事件多播器（Event Multicaster）扮演什么角色？默认实现类`SimpleApplicationEventMulticaster`是如何工作的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">事件多播器负责将事件广播到所有符合条件的监听器。默认实现 `SimpleApplicationEventMulticaster` 内部持有一个包含所有事件监听器的列表，当 `multicastEvent()` 方法被调用时，它会遍历这个列表，并调用每个监听器的 `onApplicationEvent()` 方法。</div>
          </div>
          <div class="card-source">来源: 5. 事件多播器：事件分发的核心</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">流程</div>
          <div class="card-question">请概括Spring事件机制的三个核心执行步骤。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">流程</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. **事件发布**：组件调用 `ApplicationContext` 的 `publishEvent()` 方法发布一个事件。<br>2. **事件分发**：`ApplicationContext` 通过 `ApplicationEventMulticaster` 将事件广播给所有合适的监听器。<br>3. **监听器响应**：实现了 `ApplicationListener` 接口的监听器会收到事件，并在其 `onApplicationEvent()` 方法中执行相应的处理逻辑。</div>
          </div>
          <div class="card-source">来源: 6. Spring 事件机制的执行流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">Spring事件机制有哪些主要优点？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring事件机制的主要优点包括：<br>1. **解耦合**：事件发布者与监听者之间没有直接依赖，使系统组件更松耦合。<br>2. **灵活性**：可以方便地扩展和修改事件的发布与响应逻辑。<br>3. **异步支持**：可以通过配置支持异步事件处理，提高系统响应速度。</div>
          </div>
          <div class="card-source">来源: 7. Spring 事件机制的优缺点</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">使用Spring事件机制可能带来哪些缺点？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">主要缺点有两个：<br>1. **性能开销**：在大量事件和监听器的情况下，事件发布和监听过程可能会带来一定的性能开销。<br>2. **调试困难**：事件驱动的模式可能使得程序的执行流程不易追踪，增加了调试的复杂度。</div>
          </div>
          <div class="card-source">来源: 7. Spring 事件机制的优缺点</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Spring事件机制由哪两个基本部分组成？它们分别基于哪个核心类或接口？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring事件机制由事件发布者（Publisher）和事件监听器（Listener）两部分组成。事件本身默认基于 `ApplicationEvent` 类，而监听器则基于 `ApplicationListener` 接口来实现。</div>
          </div>
          <div class="card-source">来源: 1. Spring 事件机制概述</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
